package com.edu.learning.concurrent.sample.mode2;

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.time.Duration;
import java.time.LocalTime;
import java.util.concurrent.*;

/**
 * @author ll
 * @Date 2017/10/25 17:42
 */
public class RecursiveThreadDemo {

    private final static int NUMBER = 10000000;

    public static void main(String[] args) throws InterruptedException {
        double[] array = new double[NUMBER];
        for (int i = 0; i < NUMBER; i ++) {
            array[i] = i;
        }
        LocalTime start = LocalTime.now();
        ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("RecursiveThreadDemo - %d").build();
        ExecutorService service = new ThreadPoolExecutor(
                32,
                32,
                0L,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1024),
                threadFactory,
                new ThreadPoolExecutor.CallerRunsPolicy());
        service.execute(new ArrayTask(array, 0, NUMBER / 4));
        service.execute(new ArrayTask(array, NUMBER / 4, NUMBER / 2));
        service.execute(new ArrayTask(array, NUMBER / 2, NUMBER * 3 / 4));
        service.execute(new ArrayTask(array, NUMBER * 3 / 4, NUMBER));
        service.shutdown();
        service.awaitTermination(1, TimeUnit.DAYS);
        LocalTime end = LocalTime.now();
        System.out.println("Time span = " + Duration.between(start, end));//Time span = PT14.961S
    }

    private static class ArrayTask implements Runnable {
        final double[] array;
        final int lo, hi;

        public ArrayTask(double[] array, int lo, int hi) {
            this.array = array;
            this.lo = lo;
            this.hi = hi;
        }

        @Override
        public void run() {
            for (int i = 0; i < NUMBER; i ++) {
                array[i] = Math.sin(array[i]) + Math.cos(array[i]) + Math.tan(array[i]);
            }
        }
    }
}
